/**
 *	@file	bc_sub.c
 *	@brief	ボングリボックスアプリ サブ
 *	@author	Miyuki Iwasawa
 *	@date	08.08.04
 *
 */

#include "common.h"
#include "system/procsys.h"
#include "system/bmp_list.h"
#include "system/bmp_menu.h"
#include "system/arc_util.h"
#include "system/arc_tool.h"
#include "system/snd_tool.h"
#include "system/fontproc.h"
#include "system/pm_str.h"
#include "system/msgdata.h"
#include "system/pmfprint.h"
#include "system/buflen.h"
#include "system/window.h"
#include "system/brightness.h"
#include "system/clact_util.h"
#include "system/clact_tool.h"
#include "system/render_oam.h"
#include "system/palanm.h"
#include "system/wipe.h"
#include "system/window.h"
#include "system/font_arc.h"
#include "system/winframe.naix"
#include "gflib/touchpanel.h"
#include "msgdata/msg.naix"
#include "msgdata/msg_bong_case.h"

#include "savedata/config.h"
#include "application/bong_case.h"
#include "bc_sys.h"
#include "bc_app.h"
#include "bc_sub.h"
#include "bc_key.h"

#include "bongcase_gra.naix"
#include "data/clact_util/clact_header.naix"

#ifdef DEBUG_ONLY_FOR_iwasawa
 #undef IWASAWA_PRINT
 #define IWASAWA_PRINT(...) ((void) 0)
#endif

//選択ボックスリストデータ
typedef struct _BC_SBOX_LIST{
	u16	num;
	u8	px;
	u8	py;
	const u8* list;
}BC_SBOX_LIST;

//ぼんぐり移動エフェクト制御構造体
typedef struct _BONG_MOVE_EFF{
	BC_APPWORK*	app_wk;

	u8	seq;
	u8	time;
	u8	ct;
	u8	target;

	s16		epx,epy;
	fx32	ax,ay;
	fx32	x,y;

	CLACT_WORK_PTR act;
}BONG_MOVE_EFF;


////////////////////////////////////////////////////////////////
///データ定義

static const u8 bongcase_mlist01[] = {
 msg_sbox01_use, msg_sbox01_taste, msg_sbox01_cancel
};
static const u8 bongcase_mlist02[] = {
 msg_sbox02_decide, msg_sbox02_close
};

static const BC_SBOX_LIST bongcase_sbox_dat[2] = {
 { SBOX_POT_CT, SBOX_POT_PX, SBOX_POT_PY, bongcase_mlist01 },
 { SBOX_BALL_CT, SBOX_BALL_PX, SBOX_BALL_PY, bongcase_mlist02 },
};

///セレクトボックス　ヘッダデータ構造体
static const SELBOX_HEAD_PRM data_sbox_sel = {
	TRUE,SBOX_OFSTYPE_CENTER,	///<ループフラグ、左寄せorセンタリング

	4,	///<項目表示オフセットX座標(dot)

	DFRM_MSG,				///<フレームNo
	SBOX_PAL,				///<フレームパレットID
	0,0,					///oam BG Pri,Software Pri
	SBOX_FCGX,SBOX_WCGX,	///<ウィンドウcgx,フレームcgx
	SBOX_FCGX_SIZ,		///<BMPウィンドウ占有キャラクタ領域サイズ(char)
};

static const TCATS_OAM_INIT bongcase_coi = {
	0,128,		///< メイン	OAM管理領域・開始/終了
	0,32,		///< メイン	アフィン管理領域・開始/終了
	0,128,		///< サブ	OAM管理領域・開始/終了
	0,32,		///< サブ	アフィン管理領域・開始/終了
};
static const TCATS_CHAR_MANAGER_MAKE bongcase_ccmm = {
	BONGCASE_ACTRES_MAX,	//ID制御数
	64*1024,	//メイン画面管理サイズ(byte単位) 0/64kbyte
	16*1024,	//サブ画面管理サイズ(byte単位) 0/16kbyte
	GX_OBJVRAMMODE_CHAR_1D_32K,	//メインOBJモード指定
	GX_OBJVRAMMODE_CHAR_1D_32K,	//サブOBJモード指定
};

///TCATS_RES_ARC
static const TCATS_RESOURCE_FILE_LIST bongcase_actres_list = {
	NARC_clact_header_bongcase_chr_resdat,	// キャラクタ
	NARC_clact_header_bongcase_pal_resdat,		// パレット
	NARC_clact_header_bongcase_cell_resdat,	// セル
	NARC_clact_header_bongcase_canm_resdat,	// セルアニメ
	TCATS_RESID_NULL,							// マルチセル
	TCATS_RESID_NULL,							// マルチセルアニメ
	NARC_clact_header_bongcase_celact_cldat		// ヘッダー
};

//ぼんぐりアクター座標定義
static const u16 bong_act_pos[][2] = {
 {ACT_BONG01_PX,ACT_BONG01_PY},
 {ACT_BONG02_PX,ACT_BONG02_PY},
 {ACT_BONG03_PX,ACT_BONG03_PY},
 {ACT_BONG04_PX,ACT_BONG04_PY},
 {ACT_BONG05_PX,ACT_BONG05_PY},
 {ACT_BONG06_PX,ACT_BONG06_PY},
 {ACT_BONG07_PX,ACT_BONG07_PY},
};

#define BONG_POSX(idx) (bong_act_pos[idx][0])
#define BONG_POSY(idx) (bong_act_pos[idx][1])

////////////////////////////////////////////////////////////////
///プロトタイプ
////////////////////////////////////////////////////////////////
static void BongCaseVBlank(void * work);

static void sub_VBankSet(void);
static void sub_BGLInit(BC_APPWORK* wk);
static void sub_BGLRelease(BC_APPWORK* wk);
static void sub_2DResInit(BC_APPWORK* wk);
static void sub_2DResRelease(BC_APPWORK* wk);
static void sub_MsgDataInit(BC_APPWORK* wk);
static void sub_MsgDataRelease(BC_APPWORK* wk);
static void sub_BmpWinAdd(BC_APPWORK* wk);
static void sub_BmpWinDel(BC_APPWORK* wk);
static void sub_SelectListInit(BC_APPWORK* wk);
static void sub_SelectListRelease(BC_APPWORK* wk);

static void sub_ActorSysInit(BC_APPWORK* wk);
static void sub_ActorSysRelease(BC_APPWORK* wk);
static void sub_ActorInit(BC_APPWORK* wk);
static void sub_ActorRelease(BC_APPWORK* wk);
static void sub_ActorObjMake(BC_APPWORK* wk);
static void sub_ActorObjDelete(BC_APPWORK* wk);

static void sub_PotMoveEffSet(BC_APPWORK* wk);
static void tcb_BongMoveEff( TCB_PTR tcb, void* p_work );

static void sub_MsgMake(BC_APPWORK* wk,int idx);
static u16 sub_GetTastingMsgId(BC_APPWORK* wk,BONGJUICE_FPRM* fp,u8 mode);

#ifdef PM_DEBUG
static void deb_BmpWinAdd(BC_APPWORK* wk);
static void deb_BmpWinDel(BC_APPWORK* wk);
static void deb_JuiceParamPut(BC_APPWORK* wk);
#endif	//PM_DEBUG


////////////////////////////////////////////////////////////////
///グローバル関数
////////////////////////////////////////////////////////////////
/**
 *	@brief	リソース初期化
 */
void BongCaseResInit(BC_APPWORK* wk)
{
	sub_BGLInit( wk );
	sub_2DResInit( wk );
	sub_MsgDataInit( wk );
	sub_BmpWinAdd( wk );
	sub_SelectListInit( wk );
	sub_ActorInit( wk );

#ifdef PM_DEBUG
	deb_BmpWinAdd( wk );
#endif	//PM_DEBUG
	sys_VBlankFuncChange(BongCaseVBlank, wk);
}

/**
 *	@brief	リソース解放
 */
void BongCaseResRelease(BC_APPWORK* wk)
{
#ifdef PM_DEBUG
	deb_BmpWinDel( wk );
#endif	//PM_DEBUG

	sub_ActorRelease( wk );
	sub_SelectListRelease( wk );
	sub_BmpWinDel( wk );
	sub_MsgDataRelease( wk );
	sub_2DResRelease( wk );
	sub_BGLRelease( wk );
}

/**
 *	@brief	初期画面描画
 */
void BongCaseInitialDraw(BC_APPWORK* wk)
{
	int i;

	BCSub_BackButtonWrite(wk,BTN_ACTIVE);
	BCSub_CursorPosSet( wk );

	//タイトル
	{
		u8	siz;
		MSGMAN_GetString(wk->msg.man,msg_title,wk->msg.tmp);
		siz = FontProc_GetPrintStrWidth( FONT_SYSTEM, wk->msg.tmp, 0 );
		GF_STR_PrintColor( &wk->win[WIN_TITLE], FONT_SYSTEM, wk->msg.tmp,
			((BMP_TITLE_SX*8)-siz)/2,0, MSG_ALLPUT, FCOL_SYS_N_WHITE, NULL );
	}
	//ボングリの個数
	for(i = 0;i < BONG_COL_MAX;i++){
		BCSub_BongNumWinWrite(wk,i);
	}

	//システムメッセージ描画
	switch(wk->mode){
	case SYSMODE_POT:
		BCSub_SysMsgPotStSet(wk);
		break;
	case SYSMODE_BALL:
		BCSub_SysMsgPut(wk,MIDX_SYS_BONG01);	//渡すぼんぐりを選んでください
		break;
	case SYSMODE_NORMAL:
	default:
		BCSub_SysMsgPut(wk,MIDX_SYS_NORMAL);	//集めたボングリが入ってる
		break;
	}

#ifdef PM_DEBUG
	deb_JuiceParamPut(wk);
#endif
}

/**
 *	@brief	ぼんぐりのステート取得
 */
void BCSub_BongDataUpdate(BC_APPWORK* wk)
{
	int i;

	wk->bong.stock_num = BonguriSave_GetStockNum(wk->bong_sv);
	wk->bong.juice_rest = BonguriSave_GetJuiceRestCount(wk->bong_sv);

	//現在のジュースパラメータ取得
	BonguriSave_GetJuiceParam(wk->bong_sv,BONG_JUICE_MINE,&wk->bong.juice);
	wk->bong.mild = wk->bong.juice.mild;
	wk->bong.juice_col = BongJuice_GetJuiceColor(&wk->bong.juice);
	wk->bong.taste  = BongJuice_GetTasteLevel(&wk->bong.juice);
	BongJuice_GetFlavorParam(&wk->bong.juice,&wk->bong.flavor);

	wk->bong.pot_state = BonguriSave_GetPotState(wk->bong_sv);

	for(i = 0;i < BONG_COL_MAX;i++){
		wk->bong.num[i] = BonguriSave_GetBonguriNum(wk->bong_sv,i);
	}
#ifdef PM_DEBUG
	deb_JuiceParamPut(wk);
#endif
}

/**
 *	@brief	戻るボタン描画
 */
void BCSub_BackButtonWrite(BC_APPWORK* wk,BTN_STATE state)
{
	u32 siz;
	static const GF_PRINTCOLOR col[] = {
	 GF_PRINTCOLOR_MAKE(1,2,0),
	 GF_PRINTCOLOR_MAKE(3,4,0),
	 GF_PRINTCOLOR_MAKE(5,6,0),
	};

	CLACT_AnmChg(wk->pAct[ACT_BACK], ANM_BACK+state);
	CLACT_AnmReStart( wk->pAct[ACT_BACK]);

	GF_BGL_BmpWinDataFill( &wk->win[WIN_BACK], 0);

	siz = FontProc_GetPrintStrWidth( FONT_TOUCH, wk->msg.close, 0 );
	GF_STR_PrintColor( &wk->win[WIN_BACK], FONT_TOUCH, wk->msg.close,
		((BMP_BACK_SX*8)-siz)/2,0, MSG_NO_PUT, col[0], NULL );

	GF_BGL_BmpWinOnVReq(&wk->win[WIN_BACK]);
}

/**
 *	@brief	けってい/やめるボタン描画
 */
void BCSub_DCButtonWrite(BC_APPWORK* wk,DC_BTN_ID id,BTN_STATE state)
{
	int siz;
	static GF_PRINTCOLOR col[] = {FCOL_SYS_N_WHITE_FR,FCOL_SYS_N_WHITE_FB};
	GF_BGL_BMPWIN* win = &wk->win[WIN_BTN01+id];

	GF_BGL_BmpWinDataFill( win, 0);

	MSGMAN_GetString(wk->msg.man,msg_sbox02_decide+id,wk->msg.str);

	siz = FontProc_GetPrintStrWidth( FONT_TOUCH, wk->msg.str, 0 );
	GF_STR_PrintColor( win, FONT_TOUCH, wk->msg.str,
		((BMP_BTN_SX*8)-siz)/2,0, MSG_NO_PUT, col[id], NULL );
	GF_BGL_BmpWinOnVReq( win );

	CLACT_AnmChg(wk->pAct[ACT_BTN_D+id], ANM_BTN_D01+(id*2) + state);
	CLACT_AnmReStart( wk->pAct[ACT_BTN_D+id]);
}

/**
 *	@brief	カーソルポジション描画
 */
void BCSub_CursorPosSet(BC_APPWORK* wk)
{
	s16 x,y;
	u8 pos =BCKey_GetCursorPosNo(wk);

	switch(pos){
	case CURPOS_POT:
		x = ACT_POTT_PX+ACT_CUR_POT_OX;
		y = ACT_POTT_PY+ACT_CUR_POT_OY;
		//システムメッセージPut
		BCSub_SysMsgPotStSet(wk);
		break;
	case CURPOS_BACK:
		x = ACT_BACK_PX+ACT_CUR_BACK_OX;
		y = ACT_BACK_PY+ACT_CUR_BACK_OY;
		break;
	default:
		x = BONG_POSX(pos)+ACT_CUR_OX;
		y = BONG_POSY(pos)+ACT_CUR_OY;
		break;
	}
	CATS_ObjectPosSet(wk->pAct[ACT_CURSOR],x,y);

	BCSub_ExpMsgPut(wk);
}

/**
 *	@brief	カーソル描画状態切替
 */
void BCSub_CursorVisibleSet(BC_APPWORK* wk,BOOL draw_f)
{
	CLACT_SetDrawFlag(wk->pAct[ACT_CURSOR], draw_f );
}

/*
 *	@brief	カーソル　アニメ状態制御
 */
void BCSub_ActAnmControl(BC_APPWORK* wk,BOOL anm_f)
{
	CLACT_SetAnmFlag(wk->pAct[ACT_CURSOR], anm_f);
}

/**
 *	@brief	ボングリ個数表示制御
 */
void BCSub_BongNumWinWrite(BC_APPWORK* wk,u8 col)
{
	u8 siz;

	GF_BGL_BMPWIN*	win = &wk->win[WIN_BONG01+col];
	if(wk->bong.num[col] == 0){
		CLACT_SetDrawFlag(wk->pAct[ACT_BONG01+col], FALSE );
		GF_BGL_BmpWinOffVReq(win);
	}else{
		CLACT_SetDrawFlag(wk->pAct[ACT_BONG01+col], TRUE );

		GF_BGL_BmpWinDataFill(win,0);
		WORDSET_RegisterNumber( wk->msg.wset, 0,
				wk->bong.num[col] , 2, NUMBER_DISPTYPE_SPACE, NUMBER_CODETYPE_HANKAKU );
		WORDSET_ExpandStr( wk->msg.wset, wk->msg.tmp ,wk->msg.num_buf);
		siz = FontProc_GetPrintStrWidth( FONT_SYSTEM, wk->msg.tmp, 0 );
		GF_STR_PrintColor( win, FONT_SYSTEM, wk->msg.tmp,
			((BMP_BONG_SX*8)-siz)/2,0, MSG_NO_PUT, FCOL_SYS_N_BLACK, NULL );
		GF_BGL_BmpWinOnVReq(win);
	}
	CATS_ObjectPosSet(wk->pAct[ACT_BONG01+col],BONG_POSX(col),BONG_POSY(col));
}

/**
 *	@brief	ボール選択画面　選択個数表示
 */
void BCSub_BallSelectNumWrite(BC_APPWORK* wk,u8 num)
{
	int i;
	u8	keta[2];
	GF_BGL_BMPWIN* win;
	static const u8 ofs_x[] = {2,8};

	keta[0] = num % 10;
	keta[1] = num / 10;

	for(i = 0;i < 2;i++){
		WORDSET_RegisterNumber( wk->msg.wset, 0, keta[i] , 1,
			NUMBER_DISPTYPE_LEFT, NUMBER_CODETYPE_HANKAKU );
		WORDSET_ExpandStr( wk->msg.wset, wk->msg.tmp ,wk->msg.num_buf);

		win = &wk->win[WIN_NUM01+i];
		GF_BGL_BmpWinDataFill( win, 0 );
		GF_STR_PrintColor( win , FONT_SYSTEM, wk->msg.tmp,
			ofs_x[i],3, MSG_NO_PUT, FCOL_SYS_N_BLACK, NULL );
		GF_BGL_BmpWinOnVReq(win);

		if(wk->bong.num[wk->target] < 10){
			break;
		}
	}
}

/**
 *	@brief	ボールモード　個数選択スクリーン描画
 */
void BCSub_BallSelectScrnWrite(BC_APPWORK* wk,BOOL on)
{
	int i;

	if(on){
		ArcUtil_HDL_ScrnSet( wk->grap_h,
			NARC_bongcase_gra_bcd_ball_nscr, wk->bgl,
			DFRM_DESIGN, 0, 0, FALSE, wk->heapID);

		BCSub_BallSelectNumWrite(wk,wk->sel_num);
		BCSub_DCButtonWrite(wk,DC_BTN_DECIDE,BTN_ACTIVE);
		BCSub_DCButtonWrite(wk,DC_BTN_CANCEL,BTN_ACTIVE);

		GF_BGL_BmpWinDataFill(&wk->win[WIN_BNAME],0);
		GF_STR_PrintColor( &wk->win[WIN_BNAME] , FONT_SYSTEM, wk->msg.bong[wk->target],
			0,0, MSG_NO_PUT, FCOL_SYS_N_BLACK, NULL );
		GF_BGL_BmpWinOnVReq( &wk->win[WIN_BNAME]);

		MSGMAN_GetString(wk->msg.man,msg_bong_num_unit,wk->msg.str);
		GF_BGL_BmpWinDataFill(&wk->win[WIN_UNIT],0);
		GF_STR_PrintColor( &wk->win[WIN_UNIT] , FONT_SYSTEM, wk->msg.str,
			2,0, MSG_NO_PUT, FCOL_SYS_N_BLACK, NULL );
		GF_BGL_BmpWinOnVReq( &wk->win[WIN_UNIT]);
	}else{
		GF_BGL_ScrFill( wk->bgl, DFRM_DESIGN, 0x0000, 0, 0, 32, 24, GF_BGL_SCRWRT_PALIN);
		GF_BGL_ScrFill( wk->bgl, DFRM_MSG, 0x0000, 0, 0, 32, 24, GF_BGL_SCRWRT_PALIN);

		GF_BGL_LoadScreenV_Req( wk->bgl, DFRM_DESIGN);
		GF_BGL_LoadScreenV_Req( wk->bgl, DFRM_MSG);
	}
	for(i = ACT_BTN_D;i <= ACT_ALD02;i++){
		CLACT_SetDrawFlag(wk->pAct[i], on );
		CLACT_SetAnmFlag(wk->pAct[i], FALSE);
	}
	if(wk->bong.num[wk->target] < 10){
		CLACT_AnmChg(wk->pAct[ACT_ALU02],ANM_UP_P);
		CLACT_AnmChg(wk->pAct[ACT_ALD02],ANM_DW_P);
	}
}

/**
 *	@brief	システムメッセージ　ポットステート表示
 */
void BCSub_SysMsgPotStSet(BC_APPWORK* wk)
{
	if(wk->bong.stock_num == 0){
		BCSub_SysMsgPut(wk,MIDX_SYS_POT01);
		return;
	}
	BCSub_SysMsgPut(wk,MIDX_SYS_POT01+wk->bong.pot_state);
}

/**
 *	@brief	システムウィンドウメッセージ描画
 */
void BCSub_SysMsgPut(BC_APPWORK* wk,MSG_SYS_IDX idx)
{
	GF_BGL_BMPWIN* win;

	win = &wk->win[WIN_SYS];
	GF_BGL_BmpWinDataFill( win, 0 );

	sub_MsgMake( wk,idx);

	GF_STR_PrintSimple(	win, FONT_SYSTEM, wk->msg.str, 0, 0, MSG_NO_PUT, NULL );
	GF_BGL_BmpWinOnVReq(win);
}

/**
 *	@brief	上画面メッセージ描画
 */
void BCSub_ExpMsgPut(BC_APPWORK* wk)
{
	GF_BGL_BMPWIN* win;
	u8 pos;

	win = &wk->win[WIN_EXP];
	GF_BGL_BmpWinDataFill( win, FBMP_COL_WHITE);

	pos = BCKey_GetCursorPosNo(wk);

	if(pos == CURPOS_BACK){
		GF_BGL_BmpWinOnVReq(win);
		return;
	}
	if(pos <= CURPOS_BONG07){
		if(wk->bong.num[pos] == 0){
			GF_BGL_BmpWinOnVReq(win);
			return;
		}
		sub_MsgMake( wk,MIDX_EXP_BONG01+pos);
	}else if(wk->bong.juice_rest){
		sub_MsgMake( wk,MIDX_EXP_POT02);
	}else{
		sub_MsgMake( wk,MIDX_EXP_POT01);
	}
	GF_STR_PrintSimple(	win, FONT_SYSTEM, wk->msg.str, 0, 0, MSG_NO_PUT, NULL );
	GF_BGL_BmpWinOnVReq(win);
}

/**
 *	@brief	メイン画面会話メッセージセット
 */
void BCSub_TalkMsgPut(BC_APPWORK* wk,int idx,u8 spd)
{
	GF_BGL_BMPWIN* win;
	win = &wk->win[WIN_MSG];

	GF_BGL_BmpWinDataFill( win, FBMP_COL_WHITE );

	BmpTalkWinWrite( win, WINDOW_TRANS_OFF, BMP_TALK_WIN_CGX, BMP_TALK_WIN_PAL );

	sub_MsgMake( wk,idx);

	if(spd != MSG_NO_PUT && spd != MSG_ALLPUT){
		MsgPrintTouchPanelFlagSet( MSG_TP_ON );
		wk->msg_idx = GF_STR_PrintSimple( win, FONT_TALK, wk->msg.str, 0, 0, spd, NULL );
	}else{
		GF_STR_PrintSimple( win, FONT_TALK, wk->msg.str, 0, 0, spd, NULL );
		wk->msg_idx = 0xFF;
	}
	GF_BGL_BmpWinOnVReq(win);
}

/**
 *	@brief	会話メッセージウィンドウクリア
 */
void BCSub_TalkMsgClear(BC_APPWORK* wk)
{
	BmpTalkWinClear( &wk->win[WIN_MSG], WINDOW_TRANS_OFF);
	GF_BGL_BmpWinOffVReq(&wk->win[WIN_MSG]);
}

/**
 *	@brief	会話メッセージ　味見メッセージセット
 */
void BCSub_TalkMsgTastingPut(BC_APPWORK* wk)
{
	u16 id = 0;
	GF_BGL_BMPWIN* win;
	win = &wk->win[WIN_MSG];

	GF_BGL_BmpWinDataFill( win, FBMP_COL_WHITE );
	BmpTalkWinWrite( win, WINDOW_TRANS_OFF, BMP_TALK_WIN_CGX, BMP_TALK_WIN_PAL );

	//メイン
	id = sub_GetTastingMsgId(wk,&wk->bong.flavor.main,0);
	MSGMAN_GetString(wk->msg.man,id,wk->msg.str);
	GF_STR_PrintSimple(	win, FONT_TALK, wk->msg.str, 0, 0, MSG_NO_PUT, NULL );

	if(wk->bong.flavor.main.flavor == BONG_FLAVOR_MIX){
		GF_BGL_BmpWinOnVReq(win);
		return;
	}
	//サブ
	if(wk->bong.flavor.ct > 1){
		id = sub_GetTastingMsgId(wk,&wk->bong.flavor.sub,1);
		MSGMAN_GetString(wk->msg.man,id,wk->msg.str);
		GF_STR_PrintSimple(	win, FONT_TALK, wk->msg.str, 0, 16, MSG_NO_PUT, NULL );
	}
	//隠し
	if(wk->bong.flavor.ct > 2){
		id = sub_GetTastingMsgId(wk,&wk->bong.flavor.hide,2);
		MSGMAN_GetString(wk->msg.man,id,wk->msg.str);
		GF_STR_PrintSimple(	win, FONT_TALK, wk->msg.str, 0, 32, MSG_NO_PUT, NULL );
	}else if(wk->bong.flavor.ct  == 1 || wk->bong.flavor.ct == 2){	//すっきりした後味
		MSGMAN_GetString(wk->msg.man,msg_taste_L3_plain,wk->msg.str);
		GF_STR_PrintSimple(	win, FONT_TALK, wk->msg.str, 0, 16+(16*(wk->bong.flavor.ct-1)), MSG_NO_PUT, NULL );
	}
	GF_BGL_BmpWinOnVReq(win);
}


/**
 *	@brief	選択ボックススタート
 */
void BCSub_SBoxSet(BC_APPWORK* wk)
{
	SELBOX_HEADER head;

	MI_CpuClear8(&head,sizeof(SELBOX_HEADER));

	head.prm = data_sbox_sel;
	head.list = (const BMPLIST_DATA*)wk->slist;
	head.bgl = wk->bgl;

	head.count = bongcase_sbox_dat[wk->mode-1].num;

	wk->list_wk = SelectBoxSet(wk->sbox,&(head),wk->key_mode,
			bongcase_sbox_dat[wk->mode-1].px,bongcase_sbox_dat[wk->mode-1].py,SBOX_W,0);
}

/**
 *	@brief	選択ボックス待ち
 */
u32 BCSub_SBoxWait(BC_APPWORK* wk)
{
	u32 ret;

	ret = SelectBoxMain(wk->list_wk);
	if(ret == SBOX_SELECT_NULL){
		return SBOX_SELECT_NULL;
	}
	wk->key_mode = SelectBoxGetKTStatus(wk->list_wk);
	SelectBoxExit(wk->list_wk);

	return ret;
}

/**
 *	@brief	YesNoボタン初期化
 */
void BCSub_YesNoBtnSet(BC_APPWORK* wk)
{
	TOUCH_SW_PARAM param;
	MI_CpuClear8(&param,sizeof(TOUCH_SW_PARAM));

	param.p_bgl  = wk->bgl;
	param.bg_frame = BMP_YESNO_FRM;
	param.char_offs = BMP_YESNO_CGX;
	param.pltt_offs = BMP_YESNO_PAL;
	param.x		= BMP_YESNO_PX;
	param.y		= BMP_YESNO_PY;
	param.kt_st = wk->key_mode;
	param.key_pos = 1;
	TOUCH_SW_Init( wk->ynbtn_wk, &param );
}

/**
 *	@brief	YesNoボタン待ち
 */
int BCSub_YesNoBtnWait(BC_APPWORK* wk)
{
	int ret;
	int mode;
	ret = TOUCH_SW_Main( wk->ynbtn_wk );
	switch(ret){
	case TOUCH_SW_RET_YES:
		mode = 1;
		break;
	case TOUCH_SW_RET_NO:
		mode = 0;
		break;
	default:
		return -1;
	}
	//現在の操作モードを取得
	wk->key_mode = TOUCH_SW_GetKTStatus(wk->ynbtn_wk);
	TOUCH_SW_Reset( wk->ynbtn_wk);
	return mode;
}

/**
 *	@brief	ぼんぐり選択時のアクティブ/パッシブ状態設定
 */
void BCSub_SetPassivePotMain(BC_APPWORK* wk,BONG_STATE state)
{
	int i;

	if(state == BONG_STATE_PASSIVE
		|| state == BONG_STATE_TARGET_ONLY){	//パッシブ
		for(i = 0;i < BONG_COL_MAX;i++){
			if(i == wk->target && state == BONG_STATE_TARGET_ONLY){
				CLACT_ObjModeSet( wk->pAct[ACT_BONG01+i], GX_OAM_MODE_NORMAL);
			}else{
				CLACT_ObjModeSet( wk->pAct[ACT_BONG01+i], GX_OAM_MODE_XLU);
			}
		}
		BCSub_ActAnmControl(wk,FALSE);
		BCSub_BackButtonWrite(wk,BTN_PASSIVE);
		if( wk->target < BONG_COL_MAX )
		{
			CLACT_DrawPriorityChg( wk->pAct[ACT_BONG01+wk->target], ACT_SPRI_BONG_A);
		}
	}else{
		for(i = 0;i < BONG_COL_MAX;i++){
			CLACT_ObjModeSet( wk->pAct[ACT_BONG01+i], GX_OAM_MODE_NORMAL);
		}
		BCSub_ActAnmControl(wk,TRUE);
		BCSub_BackButtonWrite(wk,BTN_ACTIVE);
		if( wk->target < BONG_COL_MAX )
		{
			CLACT_DrawPriorityChg( wk->pAct[ACT_BONG01+wk->target], ACT_SPRI_BONG);
		}
	}
}

/**
 *	@brief	ぼんぐり掴みエフェクト
 */
BOOL BCSub_BongCatchEff(BC_APPWORK* wk,BOOL flag)
{
	if(flag){	//catch
		switch(wk->sub_seq){
		case 0:
			CLACT_AnmChg(wk->pAct[ACT_CURSOR], ANM_CUR_R);
			wk->ct = 0;
			wk->sub_seq++;
			break;
		case 1:
			CATS_ObjectPosMove(wk->pAct[ACT_CURSOR], 0, 2);
			CATS_ObjectPosMove(wk->pAct[ACT_BONG01+wk->target], 0, -1);
			if(wk->ct++ < 2){
				break;
			}
			CLACT_AnmChg(wk->pAct[ACT_CURSOR], ANM_CUR_C);
			wk->ct = 0;
			wk->sub_seq = 0;
			return TRUE;
		}
	}else{	//release
		switch(wk->sub_seq){
		case 0:
			CLACT_AnmChg(wk->pAct[ACT_CURSOR], ANM_CUR_R);
			wk->ct = 0;
			wk->sub_seq++;
			break;
		case 1:
			CATS_ObjectPosMove(wk->pAct[ACT_CURSOR], 0, -2);
			if(wk->ct++ < 3){
				break;
			}
			CLACT_AnmChg(wk->pAct[ACT_CURSOR], ANM_CUR_N);
			wk->ct = 0;
			wk->sub_seq = 0;
			return TRUE;
		}

	}
	return FALSE;
}

/**
 *	@brief	ぼんぐり移動エフェクトタスク生成
 */
void BCSub_BongMoveEffSet(BC_APPWORK* wk,u8 id,u8 dir)
{
	BONG_MOVE_EFF* bp;
	s16		sx,sy,dx,dy;

	bp = sys_AllocMemory(wk->heapID,sizeof(BONG_MOVE_EFF));
	MI_CpuClear8(bp,sizeof(BONG_MOVE_EFF));

	bp->app_wk = wk;
	bp->target = wk->target;
	if(id == MOVE_BONG){
		bp->act = wk->pAct[ACT_BONG01+wk->target];
	}else{
		bp->act = wk->pAct[ACT_CURSOR];
	}
	CATS_ObjectPosGet(bp->act, &sx, &sy);

	if(dir == MOVE_TO_POT){
		bp->epx = ACT_POTT_PX + (id*ACT_CUR_OX);
		bp->epy = ACT_POTT_PY + (id*(ACT_CUR_OY+BONG_CUR_OFS_Y));
	}else{
		bp->epx = BONG_POSX(bp->target) + (id*ACT_CUR_OX);
		bp->epy = BONG_POSY(bp->target) + (id*(ACT_CUR_OY+BONG_CUR_OFS_Y));
	}
	dx = bp->epx-sx;
	dy = bp->epy-sy;

	if(MATH_ABS(dx) >= MATH_ABS(dy)){
		bp->time = MATH_ABS(dx) / 8;
		IWASAWA_PRINT("dx = %d, time = %d\n",MATH_ABS(dx),bp->time);
	}else{
		bp->time = MATH_ABS(dy) / 8;
		IWASAWA_PRINT("dy = %d, time = %d\n",MATH_ABS(dy),bp->time);
	}
	bp->x = FX32_CONST(sx);
	bp->y = FX32_CONST(sy);

	bp->ct = 0;

	bp->ax = FX_Div(FX32_CONST(dx),FX32_CONST(bp->time));
	bp->ay = FX_Div(FX32_CONST(dy),FX32_CONST(bp->time));

	TCB_Add( tcb_BongMoveEff, bp, 0);
	++wk->eff_tcb_ct;
}

////////////////////////////////////////////////////////////////
///ローカル関数
////////////////////////////////////////////////////////////////
/**
 *	@brief	VBlank関数
 */
static void BongCaseVBlank(void * work)
{
	BC_APPWORK* wk = (BC_APPWORK*)work;
	//アクター転送
	if(wk->pActSys != NULL){
		CATS_RenderOamTrans();
	}
	NNS_GfdDoVramTransfer();	//VRam転送マネージャ実行
	GF_BGL_VBlankFunc( wk->bgl );
	OS_SetIrqCheckFlag( OS_IE_V_BLANK);
}

/**
 *	@brief	vramバンク設定
 */
static void sub_VBankSet(void)
{
	GF_BGL_DISPVRAM vramSetTable = {
		GX_VRAM_BG_128_A,				// メイン2DエンジンのBG
		GX_VRAM_BGEXTPLTT_NONE,			// メイン2DエンジンのBG拡張パレット
		GX_VRAM_SUB_BG_128_C,			// サブ2DエンジンのBG
		GX_VRAM_SUB_BGEXTPLTT_NONE,		// サブ2DエンジンのBG拡張パレット
		GX_VRAM_OBJ_64_E,				// メイン2DエンジンのOBJ
		GX_VRAM_OBJEXTPLTT_NONE,		// メイン2DエンジンのOBJ拡張パレット
		GX_VRAM_SUB_OBJ_16_I,			// サブ2DエンジンのOBJ
		GX_VRAM_SUB_OBJEXTPLTT_NONE,	// サブ2DエンジンのOBJ拡張パレット
		GX_VRAM_TEX_NONE,				// テクスチャイメージスロット
		GX_VRAM_TEXPLTT_NONE			// テクスチャパレットスロット
	};
	GF_Disp_SetBank( &vramSetTable );
}
/*
 *	@brief	BGL初期化
 */
static void sub_BGLInit(BC_APPWORK* wk)
{
	sub_VBankSet();

	wk->bgl = GF_BGL_BglIniAlloc(wk->heapID);
	{	//BG SYSTEM
		GF_BGL_SYS_HEADER BGsys_data = {
			GX_DISPMODE_GRAPHICS,GX_BGMODE_0,GX_BGMODE_0,GX_BG0_AS_2D
		};
		GF_BGL_InitBG(&BGsys_data);
	}
	//上画面をサブ,下画面をメインに切り替え
	GX_SetDispSelect(GX_DISP_SELECT_SUB_MAIN);

	{	// 上画面　テキスト面
		GF_BGL_BGCNT_HEADER TextBgCntDat = {
			0, 0, 0x800, 0, GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0xf800, GX_BG_CHARBASE_0x10000, GX_BG_EXTPLTT_01,
			UFRM_MSG_PRI, 0, 0, FALSE
		};
		GF_BGL_BGControlSet( wk->bgl, UFRM_MSG, &TextBgCntDat, GF_BGL_MODE_TEXT );
		GF_BGL_ScrClear( wk->bgl, UFRM_MSG );
	}

	{	// 上画面　背景
		GF_BGL_BGCNT_HEADER TextBgCntDat = {
			0, 0, 0x800, 0, GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0xf000, GX_BG_CHARBASE_0x00000, GX_BG_EXTPLTT_01,
			UFRM_BACK_PRI, 0, 0, FALSE
		};
		GF_BGL_BGControlSet( wk->bgl, UFRM_BACK, &TextBgCntDat, GF_BGL_MODE_TEXT );
		GF_BGL_ScrClear( wk->bgl, UFRM_BACK );
	}

	{	// 下画面　テキスト面(各種ウィンドウ)
		GF_BGL_BGCNT_HEADER TextBgCntDat = {
			0, 0, 0x800, 0, GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0xf800, GX_BG_CHARBASE_0x10000, GX_BG_EXTPLTT_01,
			DFRM_MSG_PRI, 0, 0, FALSE
		};
		GF_BGL_BGControlSet( wk->bgl, DFRM_MSG, &TextBgCntDat, GF_BGL_MODE_TEXT );
		GF_BGL_ScrClear( wk->bgl, DFRM_MSG );
	}
	{	// 下画面　デザイン面
		GF_BGL_BGCNT_HEADER TextBgCntDat = {
			0, 0, 0x800, 0, GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0xf000, GX_BG_CHARBASE_0x00000, GX_BG_EXTPLTT_01,
			DFRM_DESIGN_PRI, 0, 0, FALSE
		};
		GF_BGL_BGControlSet( wk->bgl, DFRM_DESIGN, &TextBgCntDat, GF_BGL_MODE_TEXT );
		GF_BGL_ScrClear( wk->bgl, DFRM_DESIGN );
	}
	{	// 下画面 ベーステキスト描画面
		GF_BGL_BGCNT_HEADER TextBgCntDat = {
			0, 0, 0x800, 0, GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0xe800, GX_BG_CHARBASE_0x10000, GX_BG_EXTPLTT_01,
			DFRM_TEXT_PRI, 0, 0, FALSE
		};
		GF_BGL_BGControlSet( wk->bgl, DFRM_TEXT, &TextBgCntDat, GF_BGL_MODE_TEXT );
		GF_BGL_ScrClear( wk->bgl, DFRM_TEXT );
	}

	{	// 下画面　背景
		GF_BGL_BGCNT_HEADER TextBgCntDat = {
			0, 0, 0x800, 0, GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0xe000, GX_BG_CHARBASE_0x00000, GX_BG_EXTPLTT_01,
			DFRM_BACK_PRI, 0, 0, FALSE
		};
		GF_BGL_BGControlSet( wk->bgl, DFRM_BACK, &TextBgCntDat, GF_BGL_MODE_TEXT );
		GF_BGL_ScrClear( wk->bgl, DFRM_BACK );
	}


	GF_BGL_ClearCharSet( UFRM_MSG, 32, 0, wk->heapID );
	GF_BGL_ClearCharSet( UFRM_BACK, 32, 0, wk->heapID );
	GF_BGL_ClearCharSet( DFRM_MSG, 32, 0, wk->heapID );
	GF_BGL_ClearCharSet( DFRM_DESIGN, 32, 0, wk->heapID );
	GF_BGL_ClearCharSet( DFRM_TEXT, 32, 0, wk->heapID );
	GF_BGL_ClearCharSet( DFRM_BACK, 64, 0, wk->heapID );
}

/**
 * @brief	BGL解放
 */
static void sub_BGLRelease(BC_APPWORK* wk)
{

	GF_BGL_BGControlExit(wk->bgl, DFRM_BACK );
	GF_BGL_BGControlExit(wk->bgl, DFRM_TEXT );
	GF_BGL_BGControlExit(wk->bgl, DFRM_DESIGN );
	GF_BGL_BGControlExit(wk->bgl, DFRM_MSG );
	GF_BGL_BGControlExit(wk->bgl, UFRM_BACK );
	GF_BGL_BGControlExit(wk->bgl, UFRM_MSG );

	sys_FreeMemoryEz(wk->bgl);

	//上画面をメイン,下画面をサブに戻す
	GX_SetDispSelect(GX_DISP_SELECT_MAIN_SUB);
}
/**
 * @brief	2Dリソース初期化
 */
static void sub_2DResInit(BC_APPWORK* wk)
{
	ARCHANDLE* handle;

	//アーカイブのハンドルを取得
	handle = ArchiveDataHandleOpen(ARC_BONG_CASE_GRA,wk->heapID);

	//メイン下画面背景転送
	ArcUtil_HDL_PalSet( handle,
			NARC_bongcase_gra_bcase_d_nclr,PALTYPE_MAIN_BG, 0, 0, wk->heapID);
	ArcUtil_HDL_BgCharSet( handle,
			NARC_bongcase_gra_bcase_d_ncgr, wk->bgl, DFRM_BACK, 0, 0, FALSE, wk->heapID);
	ArcUtil_HDL_ScrnSet( handle,
			NARC_bongcase_gra_bcd_back_nscr, wk->bgl, DFRM_BACK, 0, 0, FALSE, wk->heapID);

	//サブ上画面背景転送
	ArcUtil_HDL_PalSet( handle,
			NARC_bongcase_gra_bcase_u_nclr,PALTYPE_SUB_BG, 0, 0, wk->heapID);
	ArcUtil_HDL_BgCharSet( handle,
			NARC_bongcase_gra_bcase_u_ncgr, wk->bgl, UFRM_BACK, 0, 0, FALSE, wk->heapID);
	ArcUtil_HDL_ScrnSet( handle,
			NARC_bongcase_gra_bcu_back_nscr, wk->bgl, UFRM_BACK, 0, 0, FALSE, wk->heapID);

	wk->grap_h = handle;
	//会話ウインドウグラフィック転送
	TalkWinGraphicSet(wk->bgl,DFRM_MSG,
		BMP_TALK_WIN_CGX, BMP_TALK_WIN_PAL,wk->win_type, wk->heapID);
	TalkFontPaletteLoad( PALTYPE_MAIN_BG, TALK_FONT_PAL*0x20, wk->heapID );
	TalkFontPaletteLoad( PALTYPE_SUB_BG, TALK_FONT_PAL*0x20, wk->heapID );

	//ブレンド設定
	G2_SetBlendAlpha(ALPHA_MASK_1ST,ALPHA_MASK_2ND,ALPHA_FIRST,ALPHA_SECOND);

}

/**
 * @brief	2Dリソース解放
 */
static void sub_2DResRelease(BC_APPWORK* wk)
{
	//ハンドル解放
	ArchiveDataHandleClose( wk->grap_h );
	G2_SetBlendAlpha(GX_BLEND_PLANEMASK_NONE,GX_BLEND_PLANEMASK_NONE,31,0);
}

/**
 *	@brief	メッセージデータ初期化
 */
static void sub_MsgDataInit(BC_APPWORK* wk)
{
	int i;

	//タッチフォントロード
	FontProc_LoadFont(FONT_TOUCH,wk->heapID);

	wk->msg.man = MSGMAN_Create(MSGMAN_TYPE_NORMAL,ARC_MSG,
			NARC_msg_bong_case_dat,wk->heapID);

	wk->msg.wset = WORDSET_CreateEx(WORDSET_BC_BUFNUM,WORDSET_BC_BUFLEN,wk->heapID);
	wk->msg.tmp = STRBUF_Create(BC_MSG_BUFLEN,wk->heapID);
	wk->msg.str = STRBUF_Create(BC_MSG_BUFLEN,wk->heapID);

	wk->msg.close = MSGMAN_AllocString(wk->msg.man,msg_close);
	wk->msg.num_buf = MSGMAN_AllocString(wk->msg.man,msg_bong_num);
	for(i = 0;i < MIDX_EXP_MAX;i++){
		wk->msg.exp[i] = MSGMAN_AllocString(wk->msg.man,msg_exp_normal+i);
	}
	for(i = 0;i < BONG_COL_MAX;i++){
		wk->msg.bong[i] = MSGMAN_AllocString(wk->msg.man,msg_bonguri01+i);
	}
}

/**
 *	@brief	メッセージデータ解放
 */
static void sub_MsgDataRelease(BC_APPWORK* wk)
{
	int i;

	//文字列バッファ削除
	for(i = 0;i < BONG_COL_MAX;i++){
		STRBUF_Delete(wk->msg.bong[i]);
	}
	for(i = 0;i < MIDX_EXP_MAX;i++){
		STRBUF_Delete(wk->msg.exp[i]);
	}
	STRBUF_Delete(wk->msg.num_buf);
	STRBUF_Delete(wk->msg.close);
	STRBUF_Delete(wk->msg.str);
	STRBUF_Delete(wk->msg.tmp);
	WORDSET_Delete(wk->msg.wset);

	MSGMAN_Delete(wk->msg.man);

	//タッチフォントアンロード
	FontProc_UnloadFont(FONT_TOUCH);
}

/**
 *	@brief	BMPウィンドウ初期化
 */
static void sub_BmpWinAdd(BC_APPWORK* wk)
{
	int i;

	static const BMPWIN_DAT BmpWinData[] = {
	 {	// 「メッセージウィンドウ」
		BMP_MSG_FRM, BMP_MSG_PX, BMP_MSG_PY,
		BMP_MSG_SX, BMP_MSG_SY, BMP_MSG_PAL, BMP_MSG_CGX
	 },
	 {	// 「システムメッセージウィンドウ」
		BMP_SYS_FRM, BMP_SYS_PX, BMP_SYS_PY,
		BMP_SYS_SX, BMP_SYS_SY, BMP_SYS_PAL, BMP_SYS_CGX
	 },
	 {	// 「もどるボタン」
		BMP_BACK_FRM, BMP_BACK_PX, BMP_BACK_PY,
		BMP_BACK_SX, BMP_BACK_SY, BMP_BACK_PAL, BMP_BACK_CGX
	 },
	 {	// 「タイトルウィンドウ」
		BMP_TITLE_FRM, BMP_TITLE_PX, BMP_TITLE_PY,
		BMP_TITLE_SX, BMP_TITLE_SY, BMP_TITLE_PAL, BMP_TITLE_CGX
	 },
	 {	// 「上画面説明ウィンドウ」
		BMP_EXP_FRM, BMP_EXP_PX, BMP_EXP_PY,
		BMP_EXP_SX, BMP_EXP_SY, BMP_EXP_PAL, BMP_EXP_CGX
	 },
	 {	// 「ボングリ名ウィンドウ」
		BMP_BNAME_FRM, BMP_BNAME_PX, BMP_BNAME_PY,
		BMP_BNAME_SX, BMP_BNAME_SY, BMP_BNAME_PAL, BMP_BNAME_CGX
	 },
	 {	// 「ボタンウィンドウ」
		BMP_BTN_FRM, BMP_BTN_PX, BMP_BTN01_PY,
		BMP_BTN_SX, BMP_BTN_SY, BMP_BTN_PAL, BMP_BTN01_CGX
	 },
	 {	// 「ボタンウィンドウ」
		BMP_BTN_FRM, BMP_BTN_PX, BMP_BTN02_PY,
		BMP_BTN_SX, BMP_BTN_SY, BMP_BTN_PAL, BMP_BTN02_CGX
	 },
	 {	// 「数値ウィンドウ」
		BMP_NUM_FRM, BMP_NUM01_PX, BMP_NUM_PY,
		BMP_NUM_SX, BMP_NUM_SY, BMP_NUM_PAL, BMP_NUM01_CGX
	 },
	 {	// 「数値ウィンドウ」
		BMP_NUM_FRM, BMP_NUM02_PX, BMP_NUM_PY,
		BMP_NUM_SX, BMP_NUM_SY, BMP_NUM_PAL, BMP_NUM02_CGX
	 },
	 {	// 「単位ウィンドウ」
		BMP_UNIT_FRM, BMP_UNIT_PX, BMP_UNIT_PY,
		BMP_UNIT_SX, BMP_UNIT_SY, BMP_UNIT_PAL, BMP_UNIT_CGX
	 },
	};

	for( i=0; i<WIN_BONG01; i++ ){
		GF_BGL_BmpWinAddEx( wk->bgl, &wk->win[i], &BmpWinData[i] );
		GF_BGL_BmpWinDataFill( &wk->win[i], 0 );
	}
	for( i = 0;i < BONG_COL_MAX;i++){
		GF_BGL_BmpWinAdd( wk->bgl, &wk->win[i+WIN_BONG01], BMP_BONG_FRM,
			(i%2)*BMP_BONG_OX+BMP_BONG_PX, (i*BMP_BONG_OY)+BMP_BONG_PY,
			BMP_BONG_SX, BMP_BONG_SY, BMP_BONG_PAL, (BMP_BONG_CGX_SIZ*i) + BMP_BONG_CGX );
		GF_BGL_BmpWinDataFill( &wk->win[i+WIN_BONG01], 0 );
	}
	//YesNoボタンシステムワーク確保
	wk->ynbtn_wk = TOUCH_SW_AllocWork(wk->heapID);
}

/**
 *	@brief	BMPウィンドウ解放
 */
static void sub_BmpWinDel(BC_APPWORK* wk)
{
	int i;
	for( i=0; i<WIN_MAX; i++ ){
		GF_BGL_BmpWinOff( &wk->win[i] );
		GF_BGL_BmpWinDel( &wk->win[i] );
	}
	//YesNoボタンシステムワーク解放
	TOUCH_SW_FreeWork( wk->ynbtn_wk );
}

/**
 *	@brief	選択ボックスリスト初期化
 */
static void sub_SelectListInit(BC_APPWORK* wk)
{
	int i;
	const BC_SBOX_LIST* dat;

	if(wk->mode == SYSMODE_NORMAL){
		return;
	}
	dat = &bongcase_sbox_dat[wk->mode-1];

	//BMPリスト領域作成
	wk->slist = BMP_MENULIST_Create(dat->num,wk->heapID);

	for(i = 0;i < dat->num;i++){
		BMP_MENULIST_AddArchiveString(wk->slist,wk->msg.man,dat->list[i],i);
	}
}

/**
 *	@brief	選択ボックスリスト解放
 */
static void sub_SelectListRelease(BC_APPWORK* wk)
{
	if(wk->mode == SYSMODE_NORMAL){
		return;
	}
	//リスト解放
	BMP_MENULIST_Delete(wk->slist);
	wk->slist = NULL;
}

/**
 *	@brief	セルアクターシステム初期化
 */
static void sub_ActorSysInit(BC_APPWORK* wk)
{
	initVramTransferManagerHeap(32,wk->heapID);

	//セルアクターシステム初期化
	wk->pActSys = CATS_AllocMemory(wk->heapID);

	CATS_SystemInit( wk->pActSys,
		&bongcase_coi,&bongcase_ccmm,BONGCASE_ACTPAL_NUM );

	//OAM初期化
	REND_OAM_UtilOamRamClear_Main(wk->heapID);
	REND_OAM_UtilOamRamClear_Sub(wk->heapID);

	//セルアクターリソース初期化
	wk->pActRes = CATS_ResourceCreate(wk->pActSys);
	CATS_ClactSetInit( wk->pActSys, wk->pActRes,BC_ACTOR_MAX);

	CATS_ResourceLoadBinaryEx( wk->pActSys, wk->pActRes,
		&bongcase_actres_list,CATS_CGXOFS_AREA,CATS_PLTTOFS_AREA);

	wk->sbox = SelectBoxSys_AllocWork( wk->heapID, NULL );
}

/**
 *	@brief	セルアクターシステム解放
 */
static void sub_ActorSysRelease(BC_APPWORK* wk)
{
	SelectBoxSys_Free(wk->sbox);

	//リソース解放
	CATS_ResourceDestructor(wk->pActSys,wk->pActRes);
	wk->pActRes = NULL;

	//システムワーク解放
	CATS_FreeMemory(wk->pActSys);
	wk->pActSys = NULL;
	DellVramTransferManager();

	//OAM初期化
	REND_OAM_UtilOamRamClear_Main(wk->heapID);
}
/*
 *	@brief	セルアクター初期化
 */
static void sub_ActorInit(BC_APPWORK* wk)
{
	sub_ActorSysInit(wk);
	sub_ActorObjMake(wk);

	GF_Disp_GX_VisibleControl( GX_PLANEMASK_OBJ, VISIBLE_ON );
}

/**
 *	@brief	セルアクター解放
 */
static void sub_ActorRelease(BC_APPWORK* wk)
{
	GF_Disp_GX_VisibleControl( GX_PLANEMASK_OBJ, VISIBLE_OFF );

	sub_ActorObjDelete(wk);
	sub_ActorSysRelease(wk);
}

/**
 *	@brief	セルアクターオブジェクト作成
 */
static void sub_ActorObjMake(BC_APPWORK* wk)
{
	int i;
	u8	idx;

	static const TCATS_OBJECT_ADD_PARAM	ActAddParam[] =
	{
		{	// 戻るボタン
			ACTRES_NORMAL,	//ID
			ACT_BACK_PX, ACT_BACK_PY, 0,	//x,y,z
			ANM_BACK, ACT_SPRI_BACK, 0, NNS_G2D_VRAM_TYPE_2DMAIN,	//anmNO,pri,pal,d_area
			TCATS_PALMODE_AUTO, 0, 0, 0	//prm1,prm2,prm3,prm4
		},
		{	// カーソル
			ACTRES_NORMAL,	//ID
			ACT_CUR_PX, ACT_CUR_PY, 0,	//x,y,z
			ANM_CUR_N, ACT_SPRI_CURSOR, 0, NNS_G2D_VRAM_TYPE_2DMAIN,	//anmNO,pri,pal,d_area
			TCATS_PALMODE_AUTO, 0, 0, 0	//prm1,prm2,prm3,prm4
		},
		{	// ぼんぐり
			ACTRES_NORMAL,	//ID
			ACT_BONG01_PX, ACT_BONG01_PY, 0,	//x,y,z
			ANM_B_RED, ACT_SPRI_BONG, 0, NNS_G2D_VRAM_TYPE_2DMAIN,	//anmNO,pri,pal,d_area
			TCATS_PALMODE_AUTO, 0, 0, 0	//prm1,prm2,prm3,prm4
		},
		{	// ポット 本体
			ACTRES_NORMAL,	//ID
			ACT_POTB_PX, ACT_POTB_PY, 0,	//x,y,z
			ANM_POT00, ACT_SPRI_POT_B, 0, NNS_G2D_VRAM_TYPE_2DMAIN,	//anmNO,pri,pal,d_area
			TCATS_PALMODE_AUTO, 0, 0, 0	//prm1,prm2,prm3,prm4
		},
		{	// ポット 蓋
			ACTRES_NORMAL,	//ID
			ACT_POTT_PX, ACT_POTT_PY, 0,	//x,y,z
			ANM_P_CLOSE, ACT_SPRI_POT_T, 0, NNS_G2D_VRAM_TYPE_2DMAIN,	//anmNO,pri,pal,d_area
			TCATS_PALMODE_AUTO, 0, 0, 0	//prm1,prm2,prm3,prm4
		},
		{	// ボールモード　ボタン
			ACTRES_NORMAL,	//ID
			ACT_BTN_PX, ACT_BTN_PY, 0,	//x,y,z
			ANM_BTN_D01, ACT_SPRI_BTN, 0, NNS_G2D_VRAM_TYPE_2DMAIN,	//anmNO,pri,pal,d_area
			TCATS_PALMODE_AUTO, 0, 0, 0	//prm1,prm2,prm3,prm4
		},
		{	// ボールモード　↑
			ACTRES_NORMAL,	//ID
			ACT_AL_PX, ACT_AL_PY, 0,	//x,y,z
			ANM_UP, ACT_SPRI_AL, 0, NNS_G2D_VRAM_TYPE_2DMAIN,	//anmNO,pri,pal,d_area
			TCATS_PALMODE_AUTO, 0, 0, 0	//prm1,prm2,prm3,prm4
		},
	};

	for(i = 0;i <= ACT_CURSOR;i++){
		wk->pAct[i] = CATS_ObjectAdd( wk->pActSys, wk->pActRes, &ActAddParam[i] );
		CLACT_SetDrawFlag(wk->pAct[i], TRUE );
		CLACT_SetAnmFlag(wk->pAct[i], TRUE);
	}
	CLACT_BGPriorityChg( wk->pAct[ACT_CURSOR], DFRM_TEXT_PRI );

	//ぼんぐり
	for(i = 0;i < BONG_COL_MAX;i++){
		idx = ACT_BONG01+i;
		wk->pAct[idx] = CATS_ObjectAdd( wk->pActSys, wk->pActRes, &ActAddParam[2] );

		CATS_ObjectPosSet(wk->pAct[idx],BONG_POSX(i),BONG_POSY(i));
		CLACT_SetAnmFlag(wk->pAct[idx], FALSE);
		CLACT_SetDrawFlag(wk->pAct[idx], TRUE );
		CLACT_AnmChg(wk->pAct[idx], ANM_B_RED+i );
		CLACT_BGPriorityChg( wk->pAct[idx], DFRM_TEXT_PRI );
	}
	switch(wk->mode){
	case SYSMODE_POT:
		//ポット
		for(i = 0; i < 2 ;i++){
			idx = ACT_POT_B+i;
			wk->pAct[idx] = CATS_ObjectAdd( wk->pActSys, wk->pActRes, &ActAddParam[3+i] );
			CLACT_SetDrawFlag(wk->pAct[idx], TRUE );
			CLACT_SetAnmFlag(wk->pAct[idx], TRUE);
		}
		CLACT_AnmChg(wk->pAct[ACT_POT_B],ANM_POT00+wk->bong.juice_rest);
		CLACT_PaletteNoChg( wk->pAct[ACT_POT_B], ACT_POTB_PAL + wk->bong.juice_col);
		break;
	case SYSMODE_BALL:
		//ボタン
		for(i = 0; i < 2 ;i++){
			idx = ACT_BTN_D+i;
			wk->pAct[idx] = CATS_ObjectAdd( wk->pActSys, wk->pActRes, &ActAddParam[5] );
			CATS_ObjectPosSet(wk->pAct[idx],ACT_BTN_PX,ACT_BTN_PY+(i*ACT_BTN_OY));
			CLACT_SetDrawFlag(wk->pAct[idx], FALSE );
			CLACT_SetAnmFlag(wk->pAct[idx], TRUE);
			CLACT_AnmChg(wk->pAct[idx],ANM_BTN_D01+(i*2));
			CLACT_BGPriorityChg( wk->pAct[idx], DFRM_DESIGN_PRI );
		}
		//矢印
		for(i = 0; i < 4 ;i++){
			idx = ACT_ALU01+i;
			wk->pAct[idx] = CATS_ObjectAdd( wk->pActSys, wk->pActRes, &ActAddParam[6] );
			CATS_ObjectPosSet(wk->pAct[idx],ACT_AL_PX+((i/2)*ACT_AL_OX),ACT_AL_PY+((i%2)*ACT_AL_OY));
			CLACT_SetDrawFlag(wk->pAct[idx], FALSE );
			CLACT_SetAnmFlag(wk->pAct[idx], FALSE);
			CLACT_AnmChg(wk->pAct[idx],ANM_UP+((i%2)*2));
			CLACT_BGPriorityChg( wk->pAct[idx], DFRM_DESIGN_PRI );
		}
	default:
		break;
	}
}

/**
 *	@brief	セルアクターオブジェクト削除
 */
static void sub_ActorObjDelete(BC_APPWORK* wk)
{
	int i;

	for(i = 0;i < BONGCASE_ACTMAX;i++){
		if(wk->pAct[i] != NULL){
			CLACT_Delete(wk->pAct[i]);
		}
	}
}


/**
 *	@brief	ぼんぐり移動エフェクト
 */
static void tcb_BongMoveEff( TCB_PTR tcb, void* p_work )
{
	BONG_MOVE_EFF* bp = (BONG_MOVE_EFF*)p_work;
	BC_APPWORK* wk = bp->app_wk;
	VecFx32 vec;

	switch(bp->seq){
	case 0:
		vec.x = bp->x;
		vec.y = bp->y;
		vec.z = 0;

		CLACT_SetMatrix(bp->act, &vec);

		bp->x += bp->ax;
		bp->y += bp->ay;
		if(bp->ct++ < bp->time){
			return;
		}
		bp->seq++;
		break;
	case 1:
	default:
		CATS_ObjectPosSet(bp->act,bp->epx,bp->epy);
		--wk->eff_tcb_ct;

		// メモリ解放
		sys_FreeMemoryEz(p_work);
		TCB_Delete( tcb );
		break;
	}
}

/**
 *	@brief	メッセージデータ生成
 */
static void sub_MsgMake(BC_APPWORK* wk,int idx)
{
	switch(idx){
	case MIDX_SYS_STOCK01:
		WORDSET_RegisterNumber( wk->msg.wset, 0,
			BONGJUICE_STOCK_MAX-BonguriSave_GetStockNum(wk->bong_sv) , 1,
			NUMBER_DISPTYPE_LEFT, NUMBER_CODETYPE_ZENKAKU );
		break;
	case MIDX_SYS_BONG03:
		WORDSET_RegisterWord(wk->msg.wset, 0, wk->msg.bong[wk->target], PM_NEUTRAL, FALSE, PM_LANG);
		WORDSET_RegisterNumber( wk->msg.wset, 1,
			wk->sel_num , 2,
			NUMBER_DISPTYPE_LEFT, NUMBER_CODETYPE_ZENKAKU );
		break;
	case MIDX_EXP_POT02:
		MSGMAN_GetString(wk->msg.man,BongJuice_GetNameID(&wk->bong.juice)+msg_juice_flavor01,wk->msg.tmp);
		WORDSET_RegisterWord(wk->msg.wset, 0, wk->msg.tmp, PM_NEUTRAL, FALSE, PM_LANG);

		WORDSET_RegisterNumber( wk->msg.wset, 1, wk->bong.taste , 3,
			NUMBER_DISPTYPE_LEFT, NUMBER_CODETYPE_ZENKAKU );
		WORDSET_RegisterNumber( wk->msg.wset, 2, wk->bong.mild , 3,
			NUMBER_DISPTYPE_LEFT, NUMBER_CODETYPE_ZENKAKU );
		WORDSET_RegisterNumber( wk->msg.wset, 3, (BONGJUICE_STOCK_MAX-wk->bong.stock_num) , 1,
			NUMBER_DISPTYPE_LEFT, NUMBER_CODETYPE_ZENKAKU );
		break;
	default:
		MSGMAN_GetString(wk->msg.man,idx+msg_exp_normal,wk->msg.str);
		return;
	}
	MSGMAN_GetString(wk->msg.man,idx+msg_exp_normal,wk->msg.tmp);
	WORDSET_ExpandStr( wk->msg.wset, wk->msg.str ,wk->msg.tmp);
}

/**
 *	@brief	味見メッセージ生成
 */
static u16 sub_GetTastingMsgId(BC_APPWORK* wk,BONGJUICE_FPRM* fp,u8 mode)
{
	u16	id;
	u8	rank = fp->rank-1;

	IWASAWA_PRINT("mode = %d ->flavor =  %d, rank = %d\n",mode,fp->flavor,fp->rank);
	switch(mode){
	case 2:	//隠し
		if(fp->flavor == BONG_FLAVOR_NONE){	//味なし
			return msg_taste_L3_plain;
		}
		if(fp->flavor == BONG_FLAVOR_MIX){	//mix系
			return msg_taste_L3_mix;
		}
		if(fp->rank == BONGJUICE_FRANK_0){	//○○を消している
			return fp->flavor + msg_taste_L3_nohot;
		}
		return (fp->flavor*3+rank)+msg_taste_L3_hot01;
	case 1:	//サブ
		if(fp->flavor == BONG_FLAVOR_NONE){	//味なし
			return msg_taste_L3_plain;
		}
		return (fp->flavor*4+rank)+msg_taste_L2_hot01;
	case 0:	//メイン
	default:
		if(fp->flavor == BONG_FLAVOR_NONE){	//味なし
			return msg_taste_La_all0;
		}
		if(fp->flavor == BONG_FLAVOR_MIX){	//mix系
			return msg_taste_La_mix01+rank;
		}
		return (fp->flavor*6+rank)+msg_taste_L1_hot01;
	}
}


/********************************************************************************/
//////////////////////////////////////////////////////////////////////////////////
//デバッグ用
//////////////////////////////////////////////////////////////////////////////////
/********************************************************************************/
#ifdef PM_DEBUG
static void deb_BmpWinAdd(BC_APPWORK* wk)
{
	int i;
	static const BMPWIN_DAT BmpWinData[] = {
	 {	// 「デバッグ ジュース情報ウィンドウ」
		BMP_DEBJ_FRM, BMP_DEBJ_PX, BMP_DEBJ_PY,
		BMP_DEBJ_SX, BMP_DEBJ_SY, BMP_DEBJ_PAL, BMP_DEBJ_CGX
	 },
	};

	for( i=0; i < DEB_WIN_MAX; i++ ){
		GF_BGL_BmpWinAddEx( wk->bgl, &wk->deb_win[i], &BmpWinData[i] );
		GF_BGL_BmpWinDataFill( &wk->deb_win[i], 0 );
	}
	wk->deb_print = TRUE;
}

/**
 *	@brief	デバッグプリントウィンドウ破棄
 */
static void deb_BmpWinDel(BC_APPWORK* wk)
{
	int i;
	for( i=0; i < DEB_WIN_MAX; i++ ){
		GF_BGL_BmpWinOff( &wk->deb_win[i] );
		GF_BGL_BmpWinDel( &wk->deb_win[i] );
	}
	wk->deb_print = FALSE;
}

static void deb_JuiceParamPut(BC_APPWORK* wk)
{
	int i;
	s8	taste[5];
	u8	bong[5],stock_num;
	u32 walk_ct[3];
	s32 next;

	if(!wk->deb_print){
		return;
	}
	GF_BGL_BmpWinDataFill(&wk->deb_win[DEB_WIN_JUICE],0);

	//ジュースのパラメータ
	for(i = 0;i < 5;i++){
		WORDSET_RegisterNumber( wk->msg.wset, i,
			wk->bong.juice.param[i] , 2, NUMBER_DISPTYPE_SPACE, NUMBER_CODETYPE_HANKAKU );
	}
	WORDSET_RegisterNumber( wk->msg.wset, 5,
		wk->bong.mild , 3, NUMBER_DISPTYPE_SPACE, NUMBER_CODETYPE_HANKAKU );
	WORDSET_RegisterNumber( wk->msg.wset, 6,
		wk->bong.taste , 3, NUMBER_DISPTYPE_SPACE, NUMBER_CODETYPE_HANKAKU );

	MSGMAN_GetString(wk->msg.man,msg_deb_juice_prm,wk->msg.str);
	WORDSET_ExpandStr( wk->msg.wset, wk->msg.tmp ,wk->msg.str);

	GF_STR_PrintColor( &wk->deb_win[DEB_WIN_JUICE] , FONT_SYSTEM, wk->msg.tmp,
		0,0, MSG_NO_PUT, FCOL_SYS_N_BLACK, NULL );

	//歩数カウント
	BongJuiceDebug_GetWalkCount(wk->bong_sv,walk_ct);
	stock_num = BongJuiceDebug_GetStockBonguri(wk->bong_sv,bong);

	WORDSET_RegisterNumber( wk->msg.wset, 0,
		wk->now_walk_ct , 10, NUMBER_DISPTYPE_LEFT, NUMBER_CODETYPE_HANKAKU );
	WORDSET_RegisterNumber( wk->msg.wset, 1,
		stock_num , 1, NUMBER_DISPTYPE_LEFT, NUMBER_CODETYPE_HANKAKU );

	for(i = 0;i < 5;i++){
		WORDSET_RegisterNumber( wk->msg.wset, 2+i,
			bong[i] , 1, NUMBER_DISPTYPE_LEFT, NUMBER_CODETYPE_HANKAKU );
	}

	next = 100 - walk_ct[1];
	if(next < 0){
		next = 0;
	}
	WORDSET_RegisterNumber( wk->msg.wset, 7,
		walk_ct[0] , 10, NUMBER_DISPTYPE_LEFT, NUMBER_CODETYPE_HANKAKU );
	WORDSET_RegisterNumber( wk->msg.wset, 8,
		next , 3, NUMBER_DISPTYPE_LEFT, NUMBER_CODETYPE_HANKAKU );

	next = 100 - (wk->now_walk_ct - walk_ct[2]);
	if(next < 0){
		next = 0;
	}
	WORDSET_RegisterNumber( wk->msg.wset, 9,
		walk_ct[2] , 10, NUMBER_DISPTYPE_LEFT, NUMBER_CODETYPE_HANKAKU );
	WORDSET_RegisterNumber( wk->msg.wset, 10,
		next , 3, NUMBER_DISPTYPE_LEFT, NUMBER_CODETYPE_HANKAKU );

	MSGMAN_GetString(wk->msg.man,msg_deb_walk_ct,wk->msg.str);
	WORDSET_ExpandStr( wk->msg.wset, wk->msg.tmp ,wk->msg.str);

	GF_STR_PrintColor( &wk->deb_win[DEB_WIN_JUICE] , FONT_SYSTEM, wk->msg.tmp,
		0,16*3, MSG_NO_PUT, FCOL_SYS_N_BLACK, NULL );

	GF_BGL_BmpWinOnVReq( &wk->deb_win[DEB_WIN_JUICE]);
}


#endif	//PM_DEBUG

